#include "FKFileReciever.h"

#include <QFile>
#include <QDir>
#include <QFileInfo>

#include "FKLogger.h"

FKFileReciever::FKFileReciever(QObject *parent):FKFileManager(parent){
    FK_CBEGIN
    FK_CEND
}

FKFileReciever::~FKFileReciever(){
    FK_DBEGIN
    foreach(QString str,_files.keys())interruptDownloading(str);
    FK_DEND
}

void FKFileReciever::requestFile(QString file){
    if(!_files.contains(file)){
        _files.insert(file,0);
        emit fileRequest(file);
    }else{
        FK_MLOGV("file already requested",file)
    }
}

void FKFileReciever::interruptDownloading(QString file){
    if(_files.contains(file)){
        emit fileError(file);
        QFile* f=_files.take(file);
        if(f){
            f->close();
            f->remove();
            f->deleteLater();
        }
    }else{
        FK_MLOGV("cannot interrupt downloading: no such file in progress",file)
    }
}

void FKFileReciever::interruptDownloading(){
    foreach(QString str, _files.keys())interruptDownloading(str);
}

void FKFileReciever::processAnswer(QVariant var){
    QString file;
    FKFileManager::Mark mark=unpackVar(file,var);
    if(!_files.contains(file)){
        FK_MLOGV("cannot manage file action: no such file in progress",file)
        return;
    }
    switch (mark){
    case nextOne:
 //       FK_MLOG("next block DL")
        getNext(file,var);
        break;
    case newOne:
//        FK_MLOG("new file DL")
        getFirst(file,var);
        break;
    case lastOne:
//        FK_MLOG("end file DL")
        getLast(file,var);
        break;
    case errorOne:
//        FK_MLOG("error file DL")
        getError(file,var);
        break;
    default:
        FK_MLOG("cannot resolve file reciever action")
    }
}

void FKFileReciever::getNext(QString file, QVariant data){
    QFile* f=_files[file];
    if(f && f->isWritable()){
        f->write(data.toByteArray());
        emit fileRequest(file);
        emit bytesRecieved(file,f->size());
    }else{
        interruptDownloading(file);
        emit errorMessage(file,QString(tr("Error recieveing: unwritable file")));
    }
}

void FKFileReciever::getFirst(QString file, QVariant data){
    QFile* f=_files[file];
    if(!f){
        QFileInfo inf(QDir(_rootPath),data.toString());
        f=new QFile(inf.absoluteFilePath());
        _files[file]=f;
//        FK_MLOGV("Getting file 1",file)
//        FK_MLOGV("Getting file 2",data.toString())
        FK_MLOGV("Getting file 3",f->fileName())
//        FK_MLOGV("Getting file 4",_rootPath)
        inf.dir().mkpath(".");
        if(f->open(QIODevice::WriteOnly)){
            emit fileRequest(file);
        }else{
            interruptDownloading(file);
            emit errorMessage(file,QString(tr("Error recieveing: cannot open")));
        }
    }else{
        interruptDownloading(file);
        emit errorMessage(file,QString(tr("Error recieveing: overwrite order")));
    }
}

void FKFileReciever::getLast(QString file, QVariant data){
    Q_UNUSED(data)
    QFile* f=_files.take(file);
    if(f){
        f->close();
        f->deleteLater();
        emit fileRecieved(file);
    }else{
        emit fileError(file);
        emit errorMessage(file,QString(tr("Error recieveing: empty file")));
    }
}

void FKFileReciever::getError(QString file, QVariant data){
    interruptDownloading(file);
    emit errorMessage(file,data.toString());
}
